package com.snail.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONUtil;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.snail.controller.aichat.ChatRequest;
import com.snail.controller.aichat.ChatResponse;
import com.snail.eunms.QuestionTypeEnum;
import com.snail.mapper.BizMediaDocMapper;
import com.snail.mapper.BizQuestionMapper;
import com.snail.model.dto.TestQuestionDTO;
import com.snail.model.pojo.BizMediaDoc;
import com.snail.model.pojo.BizQuestion;
import com.snail.service.BizMediaDocService;
import com.snail.utils.TextSplitter;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.http.MediaType;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ysc
 * @descrpiton 使用ai生成问题，暂时使用临时的ai请求，后续从文档当中的读取关键字进行发送
 * @PARAM
 * @date 2025/7/15 10:46
 **/

@Service
public class QuestionByAiService {
    @Autowired
    BizQuestionMapper bizQuestionMapper;
    @Autowired
    BizMediaDocService bizMediaDocService;
    @Value("${dashscope.base-url}")
    private   String BASE_URL;
    @Value("${dashscope.api-key}")
    private  String API_KEY ; //
    @Value("${dashscope.model}")
    private  String model ;
    private  WebClient webClient;
    @PostConstruct
    public void ChatWithAi  () {
        this.webClient = WebClient.builder()
                .baseUrl(BASE_URL)
                .defaultHeader("Authorization", "Bearer " + API_KEY)
                .defaultHeader("Content-Type", "application/json")
                .build();
    }
    @Transactional
    public List<BizQuestion> chat(Integer type,Integer videoID) throws JsonProcessingException {
        //从枚举内当中拿到题目类型和ai的请求
        QuestionTypeEnum questionType = QuestionTypeEnum.fromCode(type);
        String userPrompt = questionType.getPromptInstruction() ;

        String reply="测试返回值";
        //根据videoid传回来的值在数据库当中搜素文档,多个返回值只用一个
        //todo 如何拿到用户的不同的笔记
        BizMediaDoc resultMarkDown = bizMediaDocService.lambdaQuery().eq(BizMediaDoc::getVideoId,videoID)
                .eq(BizMediaDoc::getFileType,1).last("LIMIT 1").one();

//        System.out.println("搜索条件"+videoID);
//        System.out.println("返回的markdown"+resultMarkDown);
        String content = resultMarkDown.getContent();
        //提取关键字
        String resultSplitter= TextSplitter.extractHeadings(content).toString();
        //发送请求的具体内容
        ChatRequest request = new ChatRequest(
                model,
                List.of(
                        new ChatRequest.Message("system", """
                          你是专业的中文测试题生成助手。
                          回复以`｛开头`｝结尾
                          请只返回JSON格式文本，格式为数组，每个元素格式如下：
                          {
                            "questionType": 数字，1-5（1单选，2多选，3填空，4判断，5简答）， 
                            "content": { 
                              "title": 题目字符串， 
                              "options": 选项数组（仅选择题需包含） 
                            }, 
                            "difficulty": 数字1-5，数字越大越难， 
                            "answer": 答案（判断题用0或1，选择题用选项字母如A或AB）， 
                            "analysis": 解析字符串 
                          }
                          严格按照该格式返回多个测试题。
                            """),
                        new ChatRequest.Message("system","根据用户的提示词设置相关的问题,尽量包含所有的范围"),
                        new ChatRequest.Message("user", userPrompt),
                        new ChatRequest.Message("user", resultSplitter))

        );
        // 打印请求体 JSON，确保发送正确，后期注释删除
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonRequest = objectMapper.writeValueAsString(request);
//        System.out.println("发送请求体 JSON:");
//        System.out.println(jsonRequest);
        //发送请求
        Mono<ChatResponse> responseMono = webClient.post()
                .uri("/chat/completions")
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(request)
                .retrieve()
                .onStatus(status -> status.is4xxClientError(), clientResponse ->
                        clientResponse.bodyToMono(String.class).flatMap(errorBody -> {
                            System.err.println("请求出错，返回内容：" + errorBody);
                            return Mono.error(new RuntimeException("4xx error: " + errorBody));
                        }))
                .bodyToMono(ChatResponse.class);
        ChatResponse response = responseMono.block();
        //在控制台查看返回的回复，确保正确，后期注释删除
        List<BizQuestion> result = new ArrayList<>();
        if (response != null && response.getChoices() != null) {
           reply = response.getChoices()[0].getMessage().getContent();
//            System.out.println("AI 回复：" + reply);
            result =saveQuestionsToDb(reply,videoID);
        } else {

        }
        List<BizQuestion> questionList = JSONUtil.toList(
                JSONUtil.parseArray( result),
                BizQuestion.class
        );
        //jackson序列化的工具
    return  questionList;
    }
/*存到mysql的函数
* */
    private List<BizQuestion> saveQuestionsToDb(String aiResponse,Integer ID) {
        List<BizQuestion> questionList = JSONUtil.toList(
                JSONUtil.parseArray(aiResponse),
                BizQuestion.class
        );
        for (BizQuestion q : questionList) {
            q.setUpdateTime(LocalDateTime.now());
            q.setCreateTime(LocalDateTime.now());
            q.setCreateBy(StpUtil.getLoginIdAsInt());//后续讨论是否要这个字段
            q.setUpdateBy(StpUtil.getLoginIdAsInt());
            q.setDeleted(0);
            q.setQuestionTags(ID);

            bizQuestionMapper.insert(q);
        }

        return questionList;
    }

    public List<BizQuestion> chatQuestion(String require,Integer type) throws JsonProcessingException {
        //从枚举内当中拿到题目类型和ai的请求
        QuestionTypeEnum questionType = QuestionTypeEnum.fromCode(type);
        String userPrompt = questionType.getPromptInstruction() ;
        //发送请求的具体内容
        ChatRequest request = new ChatRequest(
                model,
                List.of(
                        new ChatRequest.Message("system", """
                          你是专业的中文测试题生成助手。
                          回复以`｛开头`｝结尾
                          请只返回JSON格式文本，格式为数组，每个元素格式如下：
                          {
                            "questionType": 数字，1-5（1单选，2多选，3填空，4判断，5简答）， 
                            "content": { 
                              "title": 题目字符串， 
                              "options": 选项数组（仅选择题需包含） 
                            }, 
                            "difficulty": 数字1-5，数字越大越难， 
                            "answer": 答案（判断题用0或1，选择题用选项字母如A或AB）， 
                            "analysis": 解析字符串 
                          }
                          严格按照该格式返回多个测试题。
                            """),
                        new ChatRequest.Message("system","根据用户的提示词设置相关的问题,尽量包含所有的范围，你会接受到用户的题目，根据这些题目返回加难或拓展题目的考察方向"),
                        new ChatRequest.Message("user", userPrompt),
                        new ChatRequest.Message("user", require),
                        new ChatRequest.Message("user", userPrompt))
        );
        //发送请求
        Mono<ChatResponse> responseMono = webClient.post()
                .uri("/chat/completions")
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(request)
                .retrieve()
                .onStatus(status -> status.is4xxClientError(), clientResponse ->
                        clientResponse.bodyToMono(String.class).flatMap(errorBody -> {
                            System.err.println("请求出错，返回内容：" + errorBody);
                            return Mono.error(new RuntimeException("4xx error: " + errorBody));
                        }))
                .bodyToMono(ChatResponse.class);
        //从ai回复中拿到信息
        ChatResponse response = responseMono.block();
        String reply = response.getChoices()[0].getMessage().getContent();
        //将json信息转成类
        List<BizQuestion> result = new ArrayList<>();
        result=saveQuestionsToDb(reply,0);
        List<BizQuestion> questionList = JSONUtil.toList(
                JSONUtil.parseArray(result),
                BizQuestion.class
        );

        return  questionList;
    }
}
